iT邦幫忙

2026 iThome 鐵人賽

DAY 28
0
佛心分享-IT 人自學之術

從空拍到3D展示系列 第 28 篇

Day28. 解決模型載入速度神之慢

  • 分享至 

  • xImage
  •  

昨天有提到,專案上遇到兩個問題

  1. 3D model 檔案太大而無法上傳
  2. 2D map 可以上傳,但在 GitHub Pages 載入花了十來分鐘

今天實測家中的網路,112MB 的模型,不可能需要這麼多時間,所以嘗試做了點改變


一、遇到的問題:模型載入非常久

先確認是不是模型本身的問題

我直接在瀏覽器新分頁,開模型檔的網址(https://smallhand.github.io/drone_threejs/blender_output.glb),不經過我寫的程式。結果光是把這個檔案載入完,就花了 22 分鐘。

所以問題不在 Three.js 的程式,也不在瀏覽器解析模型,而是檔案從 GitHub 傳到我的電腦很慢。

是我的網路不夠快嗎?

我用 Speedtest 測了一下,下載 298.20 Mbps、上傳 97.86 Mbps,Ping 5 ms。298 Mbps 換算約每秒 37 MB(÷ 8),理論上 50 MB 只要一兩秒。可是實際花了 22 分鐘,差了好幾百倍,所以不是我的整體網速不夠。

只有連 GitHub 慢嗎?

我用 curl 這個指令列工具,不經過瀏覽器,直接測連線速度:

curl.exe -4 -m 20 -o NUL -w "速度 %{speed_download}`n" 網址
  • -4:只用 IPv4 連線。
  • -m 20:最多跑 20 秒就停止,不用等載完。
  • -o NUL:載入的內容直接丟掉,不存檔。
  • -w "...":結束後印出平均速度(單位是位元組/秒)。
    | 測試 | 結果 |
    |---|---|
    | GitHub Pages 的網址 | 20 秒只收到約 1.58 MB,平均約 83,739 bytes/秒(約 0.08 MB/秒) |
    | GitHub Pages 的另一個伺服器位址 | 一樣慢,約 68,637 bytes/秒 |
    | Cloudflare 的 50 MB 公開測速檔 | 約 27 MB/秒,1 秒多就載完 |

另外,我的手機用行動網路打開同一個網址,不到 1 分鐘就載入完。

所以結論是:同一個網址,在我這台電腦(有線 HiNet)上特別慢,連到別的網站卻很快。我無法確定原因是我家到 GitHub 的網路路徑,還是我電腦上的某個設定,因為我沒有在同一台電腦上換一條網路比較。但這已經足夠讓我決定:模型不要再放在 GitHub Pages。


二、模型放到 Cloudflare R2

我把問題和測試結果拿去請教 AI,AI 列了幾個放置模型的地方:GitHub Releases、Cloudflare R2、Cloudflare Pages、jsDelivr。我最後選 Cloudflare R2,原因如下。

1. 我的電腦連 Cloudflare 很快

上一節的測試,連 Cloudflare 是每秒 27 MB,連 GitHub Pages 只有每秒約 0.08 MB。差別這麼大,搬到 Cloudflare 的網路上是最直接的做法。

2. 免費額度夠用,而且流量不收費

依 Cloudflare 官方的 R2 定價文件,每月免費額度是:

項目 免費額度
儲存 10 GB
Class A 操作 100 萬次
Class B 操作 1,000 萬次
流量(egress) 免費

文件對流量的說明是:

There are no charges for egress bandwidth for any storage class.

一個 50 MB 到 112 MB 的模型,只占儲存額度的一小部分。每個使用者載入一次模型就是一次流量,流量不收費,對這種「檔案大、人很多」的用途很重要。

3. 沒有 GitHub 那樣的 100 MB 限制

R2 官方的限制文件寫單一物件上限是 5 TiB。模型檔不經過 git,就不會再被 GitHub 擋,原本想用的 111.97 MB 的 3D model 也可以放。

4. 為什麼不選其他的

選項 沒選的原因
Cloudflare Pages 單一檔案上限 25 MiB(文件),我的模型放不進去
GitHub Releases 官方文件寫單檔小於 2 GiB(文件),但還是在 GitHub 上,我無法確定會不會一樣慢
jsDelivr 我沒有查到它對檔案大小的限制,不確定能不能放這麼大的檔案

需要知道的限制

  • R2 要訂閱,註冊時要填付款方式,只有超過免費額度才會收費。
  • 公開網址用的是 r2.dev,官方文件說:「Public access through r2.dev subdomains is rate-limited and should only be used for development purposes.」也就是它有速率限制,只適合開發用途。正式上線要綁自己的網域。我目前是做展示用,先用 r2.dev。

三、設定 Cloudflare R2

1. 建立 bucket

註冊 Cloudflare 後,到 Storage & databases → R2 object storage,完成訂閱後建立 bucket(存放檔案的空間)。依官方文件,名稱規則:

Bucket names can only contain lowercase letters (a-z), numbers (0-9), and hyphens (-).
名稱不能以連字號開頭或結尾,長度 3 到 63 個字元。

2. 上傳模型

依官方文件:進入 bucket → Upload → 拖曳檔案,或選 select from computer。

3. 開啟公開網址

依官方文件:bucket → Settings → 啟用 public development URL,輸入 allow 確認。啟用後會得到一個 https://pub-xxxxxxxx.r2.dev 的網址,模型的完整網址就是這個網址加上檔名。

這時我直接在瀏覽器開這個網址,檔案可以載入。

4. 遇到 CORS 錯誤

我把 main.js 裡的模型路徑改成 R2 的網址,網頁執行時,Console 出現:

Access to fetch at 'https://pub-xxxxxxxx.r2.dev/3d_unseen_true.glb' from origin 'http://(我本機測試用的 IP 與 port)' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

意思是:我的網頁在 A 網站(本機測試的網址)執行,要去載入 B 網站(r2.dev)的檔案,瀏覽器會先檢查 B 有沒有明確允許 A 來載入。R2 回應裡沒有 Access-Control-Allow-Origin,所以瀏覽器擋下來。

我直接在網址列開檔案可以載入,是因為那是我自己點開的網址,不是網頁裡的程式去讀取。

5. 設定 CORS

依官方 CORS 文件:bucket → Settings → CORS Policy → Add CORS policy → JSON 分頁貼上並 Save。

[
  {
    "AllowedOrigins": [
      "http://(我本機測試用的 IP 與 port)",
      "https://smallhand.github.io"
    ],
    "AllowedMethods": ["GET", "HEAD"]
  }
]
  • AllowedOrigins:允許哪些網站來載入。第一個是我在家裡測試時,網頁的 IP 和我開的 port;第二個是部署後的網站。文件說值必須是 scheme://host[:port],不能有路徑或結尾斜線,所以第二個不能寫成 https://smallhand.github.io/drone_threejs/。
  • 本機的 IP 要跟瀏覽器網址列上的完全一致,每個 port 要分開列。
  • AllowedMethods:載入模型只需要讀取,所以是 GET 和 HEAD。
  • 文件說設定後最多 30 秒生效。

六、結果

項目 結果
電腦 幾秒內載入成功
手機 比電腦慢一些,接近 1 分鐘

和一開始放在 GitHub Pages 的 22 分鐘相比,差別很大。


小結

  • GitHub 單一檔案超過 100 MiB 會被擋,整次推送都失敗。
  • GitHub Pages 要在 repo 自己的 Settings 裡開,不是帳號層級的 Pages。
  • 部署後,同一個模型檔在我的電腦上要載入 22 分鐘,連 Cloudflare 卻只要 1 秒多。我沒辦法確定是我的網路路徑還是電腦設定造成的,但足夠決定換地方。
  • 改放 Cloudflare R2:免費額度夠用、流量不收費、沒有 100 MB 的限制,原本想用的 3D model 也能放。
  • 網頁去載入另一個網站的檔案,要在 R2 設定 CORS,AllowedOrigins 要跟瀏覽器網址列上的來源完全一致。

接下來

模型載入穩定後,明天換用手機開啟專案,看是否能正常移動、旋轉模型,然後點擊彩蛋時,是否能認出這個事件


上一篇
Day 27. 專案部署到 Github Pages 並實測
系列文
從空拍到3D展示 共 28 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言